/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package komenskyimagelinksfixer;

import cz.mzk.kramerius.fedoraaccess.FedoraConnector;
import cz.mzk.rehan.commons.DatastreamId;
import cz.mzk.rehan.commons.Dom4jUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.XPath;

/**
 * Pro každou stránky monografie/rukpisu opraví mimetype "jpeg" -> "image/jpeg"
 * datastreamů IMG_FULL a IMG_THUMB.
 * Dále přidá datastream IMG_PREVIEW se stejným obsahem, jako IMG_THUMB.
 * @author Martin Řehánek <rehan at mzk.cz>
 */
public class KomenskyFixer {

    private static final int DELAY_MILLISECONDS = 100;//so that Fedora won't be overloaded
    private static final Logger logger = Logger.getLogger(KomenskyFixer.class.getName());
    private final FedoraConnector conn;
    private final String topLevelPid;

    /**
     * 
     * @param conn
     * @param topLevelPid pid top-level objektu (např. monografie, rukopis)
     */
    public KomenskyFixer(FedoraConnector conn, String topLevelPid) {
        this.conn = conn;
        this.topLevelPid = topLevelPid;
    }

    public void run() throws InterruptedException {
        List<String> pagePids = getPidsOfPages(topLevelPid);
        for (String pagePid : pagePids) {
            Document pageDoc = conn.getObjectFoxml(pagePid);
            logger.log(Level.INFO, "fixing page {0}", pagePid);
            logger.log(Level.INFO, "fixing mimetype in IMG_FULL of {0}", pagePid);
            fixMimeTypeAndReturnUrl(pagePid, pageDoc, DatastreamId.IMG_FULL, "Obrázek v plném rozlišeni");
            logger.log(Level.INFO, "fixing mimetype in IMG_THUMB of {0}", pagePid);
            String thumbUrl = fixMimeTypeAndReturnUrl(pagePid, pageDoc, DatastreamId.IMG_THUMB, "Náhled obrázku");
            logger.log(Level.INFO, "adding IMG_PREVIEW of {0} with url {1}", new Object[]{pagePid, thumbUrl});
            conn.addExternallyReferencedDatastream(pagePid, DatastreamId.IMG_PREVIEW, thumbUrl, "image/jpeg", "Náhled obrázku");
            Thread.sleep(DELAY_MILLISECONDS);
        }
    }

    private List<String> getPidsOfPages(String monographPid) {
        Document relsExtDoc = conn.getXmlDatastreamDissemination(monographPid, DatastreamId.RELS_EXT);
        //System.out.println(relsExtDoc.asXML());
        XPath path = Dom4jUtils.createXPath("//kramerius:hasPage/@rdf:resource");
        List<Node> nodes = path.selectNodes(relsExtDoc);
        List<String> result = new ArrayList<String>(nodes.size());
        for (Node node : nodes) {
            String pid = node.getText().substring("info:fedora/".length());
            result.add(pid);
        }
        return result;
    }

    private String fixMimeTypeAndReturnUrl(String pagePid, Document pageDoc, DatastreamId dsId, String description) {
        XPath path = Dom4jUtils.createXPath("//foxml:datastream[@ID='" + dsId.toString() + "']/foxml:datastreamVersion");
        List nodes = path.selectNodes(pageDoc);
        logger.log(Level.INFO, dsId.toString() + " versions: {0}", nodes.size());
        String url = getLastUrlVersion(nodes, dsId);
        logger.log(Level.INFO, dsId.toString() + " url: {0}", url);
        //drop datastream
        conn.purgeDatastream(pagePid, dsId, "odstranění " + dsId.toString() + " kvůli nekorektnímu mimetype");
        //create new datastream with correct mimetype
        conn.addExternallyReferencedDatastream(pagePid, dsId, url, "image/jpeg", description);
        return url;
    }

    private String getLastUrlVersion(List<Element> versions, DatastreamId dsId) {
        if (versions.size() == 1) {
            return urlFromDatastreamVersion((Element) versions.get(0));
        } else {//select latest datastream version
            XPath idXpath = Dom4jUtils.createXPath("@ID");
            int latestVersion = -1;
            Element selectedDsVersion = null;
            for (Element versionEl : versions) {
                int versionId = Integer.valueOf(idXpath.selectSingleNode(versionEl).getText().substring(dsId.toString().length() + 1));
                if (versionId > latestVersion) {
                    latestVersion = versionId;
                    selectedDsVersion = versionEl;
                }
            }
            return urlFromDatastreamVersion(selectedDsVersion);
        }
    }

    private String urlFromDatastreamVersion(Element dsVersion) {
        XPath path = Dom4jUtils.createXPath("foxml:contentLocation/@REF");
        Node selectSingleNode = path.selectSingleNode(dsVersion);
        return selectSingleNode.getText();
    }
}
